package cn.edu.seu.ssny.controller.admin;

import cn.edu.seu.ssny.common.R;
import cn.edu.seu.ssny.controller.BaseController;
import cn.edu.seu.ssny.entity.*;
import cn.edu.seu.ssny.enums.ResultCodeEnum;
import cn.edu.seu.ssny.enums.StatisticsEnum;
import cn.edu.seu.ssny.exception.SsnyException;
import cn.edu.seu.ssny.service.*;
import cn.edu.seu.ssny.service.impl.StatisticsPowercostRateTypeServiceImpl;
import cn.edu.seu.ssny.service.support.IBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/admin")
public class StatisticsConfigController extends BaseController {

    @Autowired
    private IProjectService projectService;
    @Autowired
    private IStatisticsConfigService statisticsConfigService;
    @Autowired
    private IStatisticsTypeService statisticsTypeService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IStatisticsPowercostRateTypeService statisticsPowercostRateTypeService;
    @Autowired
    private IStatisticsPowercostRateConfigService statisticsPowercostRateConfigService;
    @Autowired
    private IMachineGroupService machineGroupService;
    @Autowired
    private IMachineGroupConfigService machineGroupConfigService;

    @GetMapping("/statistics/config/{projectId}")
    public String statisticsConfigHtml(@PathVariable("projectId") Integer projectId, ModelMap map) {
        Project project = projectService.find(projectId);
        List<StatisticsType> statisticsTypes = statisticsTypeService.findAll();
        map.put("statisticsTypes", statisticsTypes);
        map.put("project", project);
        return "admin/project/statistics_config";
    }

    @ResponseBody
    @GetMapping("/statistics/config/heating_powercost_device/{projectId}")
    public R getAllHeatingDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsHeatingPowerCost.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/cooling_powercost_device/{projectId}")
    public R getAllCoolingDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsCoolingPowerCost.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/heating_powercost_std_device/{projectId}")
    public R getAllHeatingStdDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsPowercostStdHeating.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/cooling_powercost_std_device/{projectId}")
    public R getAllCoolingStdDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsPowercostStdCooling.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/cooling_energy_device/{projectId}")
    public R getAllCoolingEnergyDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsCoolingEnergy.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/heating_energy_device/{projectId}")
    public R getAllHeatingEnergyDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsHeatingEnergy.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }


    @ResponseBody
    @GetMapping("/statistics/config/renew_energy_device/{projectId}")
    public R getAllRenewEnergyDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsRenewEnergy.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/coal_saved_device/{projectId}")
    public R getAllCoalSavedDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsCoalSaved.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @GetMapping("/statistics/config/carbon_emission_device/{projectId}")
    public R getAllCarbonEmissionDevice(@PathVariable("projectId") Long projectId) {
        Project project = projectService.find(Math.toIntExact(projectId));
        List<StatisticsConfig> statisticsConfigs = statisticsConfigService.getDeviceIdsByProjectIdAndStatisticsTypeId(project, StatisticsEnum.StatisticsCarbonEmission.value());
        Map<String, Object> data = new HashMap<>();
        data.put("config", statisticsConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @DeleteMapping("/statistics/config/delete/{configId}")
    public R deleteConfig(@PathVariable("configId") Long configId) {
        statisticsConfigService.delete(configId);
        return R.ok();
    }

    @GetMapping("/statistics/config/add/{projectId}/{statisticsTypeId}")
    public String addHtml(@PathVariable("projectId") Integer projectId, @PathVariable("statisticsTypeId") Long statisticsTypeId, ModelMap map) {
        Project project = projectService.find(projectId);
        List<Device> devices = deviceService.findByProject(project);
        map.put("project", project);
        map.put("devices", devices);
        map.put("statisticsTypeId", statisticsTypeId);
        return "admin/project/statistics_config_add";
    }

    @GetMapping("/statistics/config/statistics_powercost_rate_type/add_edit/{projectId}")
    public String addOrEditPowercostRateTypeHtml(@PathVariable("projectId") Integer projectId, @RequestParam(value = "statisticsPowercostRateTypeId", required = false) Integer statisticsPowercostRateTypeId, ModelMap map) {
        Project project = projectService.find(projectId);
        map.put("project", project);
        if (statisticsPowercostRateTypeId != null) {
            StatisticsPowercostRateType statisticsPowercostRateType = statisticsPowercostRateTypeService.find(statisticsPowercostRateTypeId);
            map.put("statisticsPowercostRateType", statisticsPowercostRateType);
        }
        return "admin/project/statistics_powercost_rate_type_add_edit";
    }

    @ResponseBody
    @PostMapping("/statistics/config/statistics_powercost_rate_type/add_edit")
    public R addPowercostRateType(StatisticsPowercostRateType statisticsPowercostRateType, @RequestParam("projectId") Integer projectId) {
        Project project = projectService.find(projectId);
        if (statisticsPowercostRateTypeService.findByProjectAndName(project, statisticsPowercostRateType.getName()) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_STATISTICS_POWERCOST_RATE_TYPE);
        }
        if (statisticsPowercostRateType.getId() == null) {
            //添加新的分析类别
            statisticsPowercostRateType.setProject(project);
            statisticsPowercostRateTypeService.save(statisticsPowercostRateType);
        } else {
            //更新分析类别
            statisticsPowercostRateType.setProject(project);
            statisticsPowercostRateTypeService.update(statisticsPowercostRateType);
        }
        return R.ok();
    }

    @ResponseBody
    @GetMapping("/statistics/config/statistics_powercost_rate_type/{projectId}")
    public R findPowercostRateTypeByProject(@PathVariable("projectId") Integer projectId) {
        Project project = projectService.find(projectId);
        List<StatisticsPowercostRateType> statisticsPowercostRateTypes = statisticsPowercostRateTypeService.findByProject(project);
        Map<String, Object> data = new HashMap<>();
        data.put("groups", statisticsPowercostRateTypes);
        return R.ok().data(data);
    }

    @ResponseBody
    @DeleteMapping("/statistics/config/statistics_powercost_rate_type/delete/{statisticsPowercostRateTypeId}")
    public R deleteStatisticsPowercostRateTypeByStatisticsPowercostRateTypeId(@PathVariable("statisticsPowercostRateTypeId") Integer statisticsPowercostRateTypeId) {
        StatisticsPowercostRateType statisticsPowercostRateType = statisticsPowercostRateTypeService.find(statisticsPowercostRateTypeId);
        List<StatisticsPowercostRateConfig> statisticsPowercostRateConfigs = statisticsPowercostRateConfigService.findStatisticsPowercostRateConfigsByStatisticsPowercostRateType(statisticsPowercostRateType);
        if (statisticsPowercostRateConfigs != null && statisticsPowercostRateConfigs.size() > 0) {
            throw new SsnyException(ResultCodeEnum.ERROR_STATISTICS_POWERCOST_TYPE_USING);
        }
        statisticsPowercostRateTypeService.delete(statisticsPowercostRateTypeId);
        return R.ok();
    }

    @ResponseBody
    @PostMapping("/statistics/config/add")
    public R add(@RequestParam("projectId") Integer projectId, @RequestParam("statisticsTypeId") Integer statisticsTypeId, @RequestParam("deviceId") Integer deviceId) {
        Project project = projectService.find(projectId);
        Device device = deviceService.find(deviceId);
        if (statisticsConfigService.findByStatisticsTypeIdAndProjectAndDevice(statisticsTypeId, project, device) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_STATISTICS_CONFIG);
        }
        StatisticsConfig statisticsConfig = new StatisticsConfig();
        statisticsConfig.setDevice(device);
        statisticsConfig.setProject(project);
        statisticsConfig.setStatisticsTypeId(statisticsTypeId);
        statisticsConfigService.save(statisticsConfig);
        return R.ok();
    }

    /**
     * <功能描述:
     * 根据statisticsPowercostRateTypeId返回所有对应的采集点
     *
     * @param statisticsPowercostRateTypeId
     * @return
     */
    @ResponseBody
    @GetMapping("/statistics/config/statistics_powercost_rate_config/{statisticsPowercostRateTypeId}")
    public R getStatisticsPowercostRateConfigBystatisticsPowercostRateTypeId(@PathVariable("statisticsPowercostRateTypeId") Integer statisticsPowercostRateTypeId) {
        StatisticsPowercostRateType statisticsPowercostRateType = statisticsPowercostRateTypeService.find(statisticsPowercostRateTypeId);
        List<StatisticsPowercostRateConfig> statisticsPowercostRateConfigs = statisticsPowercostRateConfigService.findStatisticsPowercostRateConfigsByStatisticsPowercostRateType(statisticsPowercostRateType);
        Map<String, Object> data = new HashMap<>();
        data.put("configs", statisticsPowercostRateConfigs);
        return R.ok().data(data);
    }

    @GetMapping("/statistics/config/powercost_rate_config/add/{projectId}/{statisticsPowercostRateTypeId}")
    public String addHtmlOnPowercostRateConfig(@PathVariable("projectId") Integer projectId, @PathVariable("statisticsPowercostRateTypeId") Long statisticsPowercostRateTypeId, ModelMap map) {
        Project project = projectService.find(projectId);
        List<Device> devices = deviceService.findByProject(project);
        map.put("devices", devices);
        map.put("statisticsPowercostRateTypeId", statisticsPowercostRateTypeId);
        return "admin/project/statistics_powercost_rate_config_add";
    }

    /**
     * 添加能耗占比配置项
     *
     * @param statisticsPowercostRateTypeId
     * @param deviceId
     * @return
     */
    @ResponseBody
    @PostMapping("/statistics/config/powercost_rate_config/add")
    public R addOnPowercostRateConfig(@RequestParam("statisticsPowercostRateTypeId") Integer statisticsPowercostRateTypeId, @RequestParam("deviceId") Integer deviceId) {
        Device device = deviceService.find(deviceId);
        StatisticsPowercostRateType statisticsPowercostRateType = statisticsPowercostRateTypeService.find(statisticsPowercostRateTypeId);
        if (statisticsPowercostRateConfigService.findByStatisticsPowercostRateTypeAndDevice(statisticsPowercostRateType, device) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_POWERCOST_RATE_CONFIG);
        }
        StatisticsPowercostRateConfig statisticsPowercostRateConfig = new StatisticsPowercostRateConfig();
        statisticsPowercostRateConfig.setDevice(device);
        statisticsPowercostRateConfig.setStatisticsPowercostRateType(statisticsPowercostRateType);
        statisticsPowercostRateConfigService.save(statisticsPowercostRateConfig);
        return R.ok();
    }

    @ResponseBody
    @DeleteMapping("/statistics/config/statistics_powercost_rate_config/delete/{statisticsPowercostRateConfigId}")
    public R deleteStatisticsPowercostRateConfigByStatisticsPowercostRateConfigId(@PathVariable("statisticsPowercostRateConfigId") Integer statisticsPowercostRateConfigId) {
        statisticsPowercostRateConfigService.delete(statisticsPowercostRateConfigId);
        return R.ok();
    }


    @GetMapping("/statistics/config/statistics_machine_group/add_edit/{projectId}")
    public String addOrEditMachineGroupHtml(@PathVariable("projectId") Integer projectId, @RequestParam(value = "machineGroupId", required = false) Integer machineGroupId, ModelMap map) {
        Project project = projectService.find(projectId);
        map.put("project", project);
        if (machineGroupId != null) {
            MachineGroup machineGroup = machineGroupService.find(machineGroupId);
            map.put("machineGroup", machineGroup);
        }
        return "admin/project/statistics_machine_group_add_edit";
    }


    @ResponseBody
    @PostMapping("/statistics/config/statistics_machine_group/add_edit")
    public R addOrEditMachineGroup(MachineGroup machineGroup, @RequestParam("projectId") Integer projectId) {
        Project project = projectService.find(projectId);
        if (machineGroupService.findByProjectAndName(project, machineGroup.getName()) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_MACHINE_GROUP);
        }
        if (machineGroup.getId() == null) {
            //添加新的机组
            machineGroup.setProject(project);
            machineGroupService.save(machineGroup);
        } else {
            //更新分析类别
            machineGroup.setProject(project);
            machineGroupService.update(machineGroup);
        }
        return R.ok();
    }


    @ResponseBody
    @GetMapping("/statistics/config/statistics_machine_group/{projectId}")
    public R findMachineGroupsByProject(@PathVariable("projectId") Integer projectId) {
        Project project = projectService.find(projectId);
        List<MachineGroup> machineGroups = machineGroupService.findByProject(project);
        Map<String, Object> data = new HashMap<>();
        data.put("groups", machineGroups);
        return R.ok().data(data);
    }


    @ResponseBody
    @DeleteMapping("/statistics/config/statistics_machine_group/delete/{machineGroupId}")
    public R deleteMachineGroupByMachineGroupId(@PathVariable("machineGroupId") Integer machineGroupId) {
        MachineGroup machineGroup = machineGroupService.find(machineGroupId);
        List<MachineGroupConfig> machineGroupConfigs = machineGroupConfigService.findMachineGroupConfigsByMachineGroup(machineGroup);
        if (machineGroupConfigs != null && machineGroupConfigs.size() > 0) {
            throw new SsnyException(ResultCodeEnum.ERROR_MACHINE_GROUP_USING);
        }
        machineGroupService.delete(machineGroup);
        return R.ok();
    }

    @GetMapping("/statistics/config/machine_group_config/add/{projectId}/{machineGroupId}")
    public String addHtmlOnMachineGroupConfig(@PathVariable("projectId") Integer projectId, @PathVariable("machineGroupId") Long machineGroupId, ModelMap map) {
        Project project = projectService.find(projectId);
        List<Device> devices = deviceService.findByProject(project);
        map.put("devices", devices);
        map.put("machineGroupId", machineGroupId);
        return "admin/project/statistics_machine_group_config_add";
    }

    /**
     * 添加能耗占比配置项
     *
     * @param machineGroupId
     * @param deviceId
     * @return
     */
    @ResponseBody
    @PostMapping("/statistics/config/machine_group_config/add")
    public R addOnMachineGroupConfig(@RequestParam("machineGroupId") Integer machineGroupId, @RequestParam("deviceId") Integer deviceId, @RequestParam("type") Integer type) {
        Device device = deviceService.find(deviceId);
        MachineGroup machineGroup = machineGroupService.find(machineGroupId);
        if (machineGroupConfigService.findByMachineGroupAndDevice(machineGroup, device) != null) {
            throw new SsnyException(ResultCodeEnum.ERROR_DUPLICATE_MACHINE_GROUP_CONFIG);
        }
        MachineGroupConfig machineGroupConfig = new MachineGroupConfig();
        machineGroupConfig.setDevice(device);
        machineGroupConfig.setMachineGroup(machineGroup);
        machineGroupConfig.setType(type);
        machineGroupConfigService.save(machineGroupConfig);
        return R.ok();
    }

    /**
     * <功能描述:
     * 根据statisticsPowercostRateTypeId返回所有对应的采集点
     *
     * @param machineGroupId
     * @return
     */
    @ResponseBody
    @GetMapping("/statistics/config/statistics_machine_group_config/{machineGroupId}/{type}")
    public R getMachineGroupConfigByMachineGroupId(@PathVariable("machineGroupId") Integer machineGroupId, @PathVariable("type") Integer type) {
        MachineGroup machineGroup = machineGroupService.find(machineGroupId);
        List<MachineGroupConfig> machineGroupConfigs = machineGroupConfigService.findMachineGroupConfigsByMachineGroupAndType(machineGroup, type);
        Map<String, Object> data = new HashMap<>();
        data.put("configs", machineGroupConfigs);
        return R.ok().data(data);
    }

    @ResponseBody
    @DeleteMapping("/statistics/config/statistics_machine_group_config/delete/{machineGroupConfigId}")
    public R deleteMachineGroupConfigByMachineGroupConfigId(@PathVariable("machineGroupConfigId") Integer machineGroupConfigId) {
        machineGroupConfigService.delete(machineGroupConfigId);
        return R.ok();
    }


//    @PostMapping("/add_edit")
//    public R add(StatisticsDevice statisticsDevice) {
//        if (statisticsDevice.getId() == null) {
//            statisticsDeviceService.save(statisticsDevice);
//        } else {
//            statisticsDeviceService.update(statisticsDevice);
//        }
//        return R.ok();
//    }

}
